﻿//*** Guidance generated code ***//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web.Mvc;

using ProjectBase.Core;

namespace $safeprojectname$
{
    public class MultiOption : SelectOptionControl<IEnumerable, MultiOption>
    {
        #region members
        #endregion members

        #region constructor
        public MultiOption() { }
        public MultiOption(bool? asReadonly = null) : base(asReadonly) { }
        #endregion constructor

        #region OnSourceProperty
        protected override void OnSourcePropertyChanged(string propertyName, IEnumerable value)
        {
            base.OnSourcePropertyChanged(propertyName, value);

            SetSelectedValues(value);
        }
        #endregion OnSourceProperty

        #region Render
        protected override void ReadControls()
        {
            Controls.Add
                (
                    AddSelect(true, " disabled ")
                );
        }

        protected override void WriteControls()
        {
            Controls.Add
                (
                    AddSelect()
                );
        }

        protected virtual Select AddSelect(bool isDisabled = false, string css = null)
        {
            return new Select()
                .SetCssClassName(GetAttribute(Attr.Class) + " multiple " + css ?? string.Empty)
                .SetName(InputName)
                .SetDisabled(isDisabled)
                .SetSize(Size ?? 5)
                .SetMultiple(true)
                .AddControls
                (
                    AddOptions().ToArray()
                );
        }

        protected virtual IEnumerable<ISelectChild> AddOptions()
        {
            var list = new List<ISelectChild>();
            foreach (var item in Data)
            {
                list.Add
                    (
                        new Option()
                            .SetText(item.Text)
                            .SetSelected(item.Selected)
                            .AddCssClassName(item.Selected ? "selected" : null)
                            .SetValue(item.Value)
                    );
            }
            return list;
        }
        #endregion Render

        #region Set public
        /// <summary>
        ///     Provides direct access to SELECT attribute size. 
        ///     This will have an impact ont the rendered row count.
        /// </summary>
        /// <param name = "size">how many option rows to be rendered</param>
        /// <returns></returns>
        public virtual MultiOption SetSize(int size)
        {
            Size = size;
            return this;
        }

        /// <summary>
        ///     Set the list (of type SelectListItem) as the data source
        ///     for the option element list rendering
        /// </summary>
        /// <param name = "items"></param>
        /// <returns></returns>
        public virtual MultiOption SetDataSource(IEnumerable<SelectListItem> items)
        {
            if (items.Is())
            {
                Items = items;
            }
            return this;
        }

        /// <summary>
        ///     List of selected values, e.g. IList&lt;int&gt; of ID's
        ///     or List of Selected entities e.g. Model.Item.Roles
        /// </summary>
        /// <param name = "selectedValues"></param>
        /// <returns></returns>
        public virtual MultiOption SetSelectedValues(IEnumerable selectedValues)
        {
            if (selectedValues.IsNull())
            {
                return this;
            }

            var list = new List<object>();
            foreach (var item in selectedValues)
            {
                var entity = item as IPersistentObject;
                if (entity.IsNull())
                {
                    SelectedValue = selectedValues;
                    return this;
                }
                list.Add(entity.IDToDisplay);
            }
            SelectedValue = list;
            return this;
        }
        #endregion Set public

        #region properties
        /// <summary>
        ///     Provides direct access to SELECT attribute size. 
        ///     This will have an impact ont the rendered row count.
        /// </summary>
        public virtual int? Size { get; set; }
        #endregion properties
    }
}